package com.fanxj.Utils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.core.JsonProcessingException;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.io.IOException;

@Service
public class OllamaService {
    private static final Logger logger = LoggerFactory.getLogger(OllamaService.class);

    ObjectMapper objectMapper = new ObjectMapper();
    RestTemplate restTemplate = new RestTemplate();
    private String apiUrl = "http://localhost:11434/api/generate";
    // 修改为 DeepSeek 模型名称，这里以 deepseek-R1 为例
    private static String modelName = "deepseek-R1";
    private double temperature = 0.3;

    private int maxTokens = 200;

    public Map<String, Object> parseQuery(String userQuery) throws IOException {
        try {
            // 打印配置信息
            logger.info("API URL: {}", apiUrl);
            logger.info("Model: {}", modelName);

            // 检查 apiUrl 和 modelName 是否为空
            if (apiUrl == null || modelName == null) {
                throw new RuntimeException("Ollama 配置错误: apiUrl 或 modelName 为空");
            }
            // 1. 构造系统提示词
            String systemPrompt = buildSystemPrompt();

            // 2. 构造请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", modelName);
            requestBody.put("prompt", systemPrompt + "\n用户输入：" + userQuery);
            requestBody.put("stream", false);
            requestBody.put("format", "json");

            // 打印请求信息
            logger.info("Sending request to Ollama: {}", apiUrl);
            logger.debug("Request body: {}", requestBody);

            Map<String, Object> options = new HashMap<>();
            options.put("temperature", temperature);
            options.put("num_predict", maxTokens);
            requestBody.put("options", options);

            // 3. 发送请求
            String response = restTemplate.postForObject(apiUrl, requestBody, String.class);

            // 打印响应信息
            logger.info("Received response from Ollama: {}", response);

            // 4. 解析响应
            return parseResponse(response);

        } catch (RestClientException e) {
            logger.error("Ollama服务通信失败: {}", e.getMessage(), e);
            throw new OllamaException("Ollama服务通信失败: " + e.getMessage(), e);
        } catch (JsonProcessingException e) {
            throw new OllamaException("响应解析失败", e);
        }
    }

    private String buildSystemPrompt() {
        return "你是一个文物数据库专家，请严格按以下规则处理输入：" +
                "1. 朝代提取" +
                "2. 类型匹配分类：绘画/法书/碑帖/铜器/金银器/漆器/珐琅器/玉石器/陶瓷/雕塑/织绣/雕刻工艺/文具/生活用具/钟表仪器/珍宝/宗教文物/武备依仗/帝后玺册/铭刻/外国文物/古籍文献/古建藏品" +
                "3. 纹样提取" +
                "4. 地域提取，把输入中的地域提取出来（34个省级行政区，其中包括4个直辖市、23个省、5个自治区、2个特别行政区）" +
                "5. 假如没有年代的话就不用返回decadeType了，" +
                "6. 如果输入中没有类型的话就不用返回groupType了，" +
                "示例输入1：帮我找宋代有植物纹样,花卉纹,莲花纹,花卉,应时花卉的瓷器\n" +
                "示例输出1：{\"decadeType\":\"宋\",\"groupType\":\"陶瓷\",\"localType\":\"未知\",\"pattern\":[\"植物纹样\",\"莲花纹\",\"花卉纹\",\"花卉\",\"应时花卉\"]}\n" +
                "示例输入2：帮我找有植物纹样的瓷器\n" +
                "示例输出2：{\"decadeType\":\"未知\",\"groupType\":\"陶瓷\",\"localType\":\"未知\",\"pattern\":[\"植物纹样\"]}\n" +
                "示例输入3：帮我找明代的文物\n" +
                "示例输出3：{\"decadeType\":\"明\",\"groupType\":\"未知\",\"localType\":\"未知\",\"pattern\":[]}\n" +
                "示例输入4：帮我找北京的文物\n" +
                "示例输出4：{\"decadeType\":\"未知\",\"groupType\":\"未知\",\"localType\":\"北京\",\"pattern\":[]}\n" +
                "以此为例";
    }

    private Map<String, Object> parseResponse(String responseBody)
            throws JsonProcessingException, IOException {

        JsonNode root = objectMapper.readTree(responseBody);

        // 检查响应结构
        if (!root.has("response")) {
            throw new OllamaException("无效的响应格式");
        }

        String responseJson = root.get("response").asText();

        // 处理空响应（兼容 Java 8）
        if (responseJson == null || responseJson.trim().isEmpty()) {
            return Collections.emptyMap();
        }
        // 转换JSON
        return objectMapper.readValue(
                responseJson,
                new com.fasterxml.jackson.core.type.TypeReference<Map<String, Object>>() {
                }
        );
    }

    // 自定义异常类
    public static class OllamaException extends RuntimeException {
        public OllamaException(String message, Throwable cause) {
            super(message, cause);
        }

        public OllamaException(String message) {
            super(message);
        }
    }
}